home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / nevow / rend.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-03-23  |  37KB  |  778 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. """Page, Fragment and other standard renderers.
  5.  
  6. This module contains classes and function responsible for rendering
  7. dynamic content and a few useful mixin classes for inheriting common
  8. functionality.
  9.  
  10. Mostly, you'll use the renderers:
  11.  
  12.  - B{Page} - Nevow's main resource type for rendering web pages and
  13.    locating child resource.
  14.  - B{Fragment} - useful for rendering more complex parts of a document
  15.    that require a set of data_* and render_* methods.
  16.  - B{sequence} - render each item in a sequence.
  17.  - B{mapping} - publish a dictionary by filling slots
  18. """
  19. from time import time as now
  20. from cStringIO import StringIO
  21. import random
  22. import warnings
  23. from zope.interface import implements, providedBy
  24. import twisted.python.components as tpc
  25. from twisted.python.reflect import qual, accumulateClassList
  26. from nevow.context import WovenContext, NodeNotFound, PageContext
  27. from nevow import inevow, tags, flat, util, url
  28. from nevow.util import log
  29. import formless
  30. from formless import iformless, annotate
  31.  
  32. def _getPreprocessors(inst):
  33.     '''
  34.     Accumulate elements from the sequences bound at the C{preprocessors}
  35.     attribute on all classes in the inheritence hierarchy of the class of
  36.     C{inst}.  A C{preprocessors} attribute on the given instance overrides
  37.     all preprocessors from the class inheritance hierarchy.
  38.     '''
  39.     if 'preprocessors' in vars(inst):
  40.         return inst.preprocessors
  41.     preprocessors = []
  42.     accumulateClassList(inst.__class__, 'preprocessors', preprocessors)
  43.     return preprocessors
  44.  
  45.  
  46. class RenderFactory(object):
  47.     implements(inevow.IRendererFactory)
  48.     
  49.     def renderer(self, context, name):
  50.         '''Return a renderer with the given name.
  51.         '''
  52.         args = []
  53.         callable = getattr(self, 'render_%s' % name, None)
  54.         if callable is None:
  55.             warnings.warn('Renderer %r missing on %s will result in an exception.' % (name, qual(type(self))), category = DeprecationWarning, stacklevel = 1)
  56.             
  57.             callable = lambda *a, **kw: context.tag["The renderer named '%s' was not found in %r." % (name, self)]
  58.         
  59.         if args:
  60.             return callable(*args)
  61.         return callable
  62.  
  63.     
  64.     render_sequence = lambda self, context, data: sequence(context, data)
  65.     
  66.     render_mapping = lambda self, context, data: mapping(context, data)
  67.     
  68.     render_string = lambda self, context, data: string(context, data)
  69.     
  70.     render_xml = lambda self, context, data: context.tag.clear()[tags.xml(data)]
  71.     
  72.     render_data = lambda self, context, data_: data(context, data_)
  73.  
  74.  
  75. class MacroFactory(object):
  76.     implements(inevow.IMacroFactory)
  77.     
  78.     def macro(self, ctx, name):
  79.         '''Return a macro with the given name.
  80.         '''
  81.         args = []
  82.         callable = getattr(self, 'macro_%s' % name, None)
  83.         if callable is None:
  84.             
  85.             callable = lambda ctx, *args: ctx.tag["The macro named '%s' was not found in %r." % (name, self)]
  86.         
  87.         if args:
  88.             return (lambda ctx: callable(ctx, *args))
  89.         return callable
  90.  
  91.  
  92.  
  93. class DataNotFoundError(Exception):
  94.     '''Raised when a data directive could not be resolved on the page or its
  95.     original attribute by the DataFactory.
  96.     '''
  97.     pass
  98.  
  99.  
  100. class DataFactory(object):
  101.     implements(inevow.IContainer)
  102.     
  103.     def child(self, context, n):
  104.         args = []
  105.         callable = getattr(self, 'data_%s' % name, None)
  106.         if callable is None:
  107.             container = inevow.IContainer(self.original, None)
  108.             if container is None:
  109.                 raise DataNotFoundError('The data named %r was not found in %r.' % (name, self))
  110.             container is None
  111.             return container.child(context, n)
  112.         callable is None
  113.         if args:
  114.             return callable(*args)
  115.         return callable
  116.  
  117.  
  118.  
  119. class FreeformChildMixin:
  120.     '''Mixin that handles locateChild for freeform segments.'''
  121.     
  122.     def locateChild(self, ctx, segments):
  123.         request = inevow.IRequest(ctx)
  124.         bindingName = None
  125.         name = segments[0]
  126.         if name.startswith('freeform_post!'):
  127.             (configurableName, bindingName) = name.split('!')[1:3]
  128.         elif name.startswith('freeform-action-post!'):
  129.             (configurableName, request.args['freeform-actee']) = name.split('!')[1:3]
  130.             bindingName = request.args['freeform-action'][0]
  131.         
  132.         if bindingName:
  133.             ctx.remember(self, inevow.IResource)
  134.             ctx.remember(request, inevow.IRequest)
  135.             cf = iformless.IConfigurableFactory(self)
  136.             
  137.             def checkC(c):
  138.                 if c is not None:
  139.                     return self.webFormPost(request, self, c, ctx, bindingName, request.args)
  140.  
  141.             return util.maybeDeferred(cf.locateConfigurable, ctx, configurableName).addCallback(checkC)
  142.         return NotFound
  143.  
  144.     
  145.     def child_freeform_hand(self, ctx):
  146.         carryoverHand = inevow.IHand(ctx, None)
  147.         if carryoverHand is not None:
  148.             inevow.ISession(ctx).setComponent(inevow.IHand, carryoverHand)
  149.             return carryoverHand
  150.         return inevow.IHand(inevow.ISession(ctx), None)
  151.  
  152.  
  153.  
  154. class ConfigurableMixin(object):
  155.     """A sane IConfigurable implementation for Fragment and Page.
  156.     Methods starting with bind_ automatically expose corresponding
  157.     method names. bind_* should return an IBinding (PropertyBinding
  158.     or MethodBinding), or, as a shortcut for MethodBinding, a list of
  159.     twoples like this:
  160.  
  161.     def bind_foo(self, ctx):
  162.         return [('argName', String()), ('anotherArg', Integer())]
  163.  
  164.     def foo(self, argName, anotherArg):
  165.         assert isinstance(argName, str)
  166.         assert isinstance(anotherArg, int)
  167.  
  168.     """
  169.     implements(iformless.IConfigurable)
  170.     
  171.     def getBindingNames(self, ctx):
  172.         '''Expose bind_* methods and attributes on this class.
  173.         '''
  174.         for name in dir(self):
  175.             if name.startswith('bind_'):
  176.                 yield name[len('bind_'):]
  177.                 continue
  178.         
  179.  
  180.     
  181.     def getBinding(self, ctx, name):
  182.         '''Massage bind_* methods and attributes into an
  183.         IBinding. The bind_* method or attribute can either
  184.         already implement IBinding or be a list of twoples
  185.         which will be massaged into a MethodBinding as
  186.         described in the ConfigurableMixin class docstring.
  187.         '''
  188.         
  189.         def _get_binding(binding):
  190.             if callable(binding):
  191.                 binding = util.maybeDeferred(binding, ctx)
  192.             
  193.             return binding
  194.  
  195.         
  196.         def _convert_list(binding):
  197.             return binding
  198.  
  199.         binding = util.maybeDeferred(getattr, self, 'bind_%s' % name)
  200.         return binding.addCallback(_get_binding).addCallback(_convert_list)
  201.  
  202.     
  203.     def getDefault(self, forBinding):
  204.         '''Get a default value for a given binding. If the
  205.         binding is a Property, get the current value of
  206.         that property off self. If not, simply return
  207.         forBinding.default.
  208.         '''
  209.         if not isinstance(forBinding, annotate.Argument):
  210.             if hasattr(self, forBinding.name):
  211.                 return getattr(self, forBinding.name)
  212.         
  213.         return forBinding.default
  214.  
  215.     
  216.     def postForm(self, ctx, bindingName, args):
  217.         '''Accept a form post to the given bindingName.
  218.         The post arguments are given in args.
  219.  
  220.         This will invoke the IInputProcessor for the
  221.         binding with the given name. If it succeeds, the
  222.         property will be modified or the method will have
  223.         been called. If it fails, a ValidateError exception
  224.         will be raised.
  225.         '''
  226.         
  227.         def _callback(binding):
  228.             ctx.remember(binding, iformless.IBinding)
  229.             ctx.remember(self, iformless.IConfigurable)
  230.             rv = iformless.IInputProcessor(binding).process(ctx, self, args)
  231.             ctx.remember(rv, inevow.IHand)
  232.             ctx.remember('%r success.' % bindingName, inevow.IStatusMessage)
  233.             return rv
  234.  
  235.         return util.maybeDeferred(self.getBinding, ctx, bindingName).addCallback(_callback)
  236.  
  237.  
  238.  
  239. class ConfigurableFactory:
  240.     '''Locates configurables by looking for methods that start with
  241.     configurable_ and end with the name of the configurable. The method
  242.     should take a single arg (other than self) - the current context.
  243.     '''
  244.     implements(iformless.IConfigurableFactory)
  245.     
  246.     def locateConfigurable(self, context, name):
  247.         '''formless.webform.renderForms calls locateConfigurable on the IConfigurableFactory
  248.         instance it retrieves from the context. It passes the "name" that was passed to it,
  249.         so if renderForms() was placed in the DOM, locateConfigurable will be called with
  250.         name = \'\'; if renderForms(\'foo\') was placed in the DOM, locateConfigurable will
  251.         be called with name = \'foo\'.
  252.  
  253.         This default implementation of locateConfigurable looks for a configurable_* method
  254.         corresponding to the name which was passed.
  255.         '''
  256.         return util.maybeDeferred(getattr(self, 'configurable_%s' % name), context).addCallback(iformless.IConfigurable)
  257.  
  258.     
  259.     def configurable_(self, context):
  260.         '''Configurable factory for use when self is a configurable;
  261.         aka it implements IConfigurable or one or more TypedInterface
  262.         subclasses. Usage:
  263.  
  264.         >>> class IFoo(TypedInterface):
  265.         ...     def bar(): pass
  266.         ...     bar = autocallable(bar)
  267.         ...
  268.         >>> class Foo(Page):
  269.         ...     implements(IFoo)
  270.         ...
  271.         ...     def bar():
  272.         ...         print "bar called through the web!"
  273.         ...
  274.         ...     def render_forms(self, ctx, data):
  275.         ...         return renderForms() # or renderForms(\'\')
  276.         ...
  277.         ...     docFactory = stan(render_forms).
  278.         '''
  279.         if filter((lambda x: issubclass(x, annotate.TypedInterface)), providedBy(self)):
  280.             warnings.warn('[0.5] Subclassing TypedInterface to declare annotations is deprecated. Please provide bind_* methods on your Page or Fragment subclass instead.', DeprecationWarning)
  281.             configurable = configurable
  282.             import formless
  283.             return configurable.TypedInterfaceConfigurable(self)
  284.         return self
  285.  
  286.     
  287.     def configurable_original(self, ctx):
  288.         """Configurable factory for use when self.original is a configurable;
  289.         aka it implements IConfigurable or one or more TypedInterface
  290.         subclasses. Usage:
  291.  
  292.  
  293.         >>> class Foo(Page):
  294.         ...     def __init__(self):
  295.         ...         self.original = SomeConfigurable()
  296.         ...     def render_forms(self, ctx, data):
  297.         ...         return renderForms('original')
  298.         ...     docFactory = stan(render_forms)
  299.         """
  300.         return self.original
  301.  
  302.  
  303. _CARRYOVER = { }
  304.  
  305. def defaultsFactory(ctx):
  306.     co = _CARRYOVER.get(ctx.tag.args.get('_nevow_carryover_', [
  307.         None])[0], None)
  308.     webform = webform
  309.     import formless
  310.     defaults = webform.FormDefaults()
  311.     if co is not None:
  312.         e = iformless.IFormErrors(co, { })
  313.         for k, v in e.items():
  314.             defaults.getAllDefaults(k).update(v.partialForm)
  315.         
  316.     
  317.     return defaults
  318.  
  319.  
  320. def errorsFactory(ctx):
  321.     co = _CARRYOVER.get(ctx.tag.args.get('_nevow_carryover_', [
  322.         None])[0], None)
  323.     webform = webform
  324.     import formless
  325.     errs = webform.FormErrors()
  326.     if co is not None:
  327.         e = iformless.IFormErrors(co, { })
  328.         for k, v in e.items():
  329.             errs.updateErrors(k, v.errors)
  330.             errs.setError(k, v.formErrorMessage)
  331.         
  332.     
  333.     return errs
  334.  
  335.  
  336. def handFactory(ctx):
  337.     co = _CARRYOVER.get(ctx.tag.args.get('_nevow_carryover_', [
  338.         None])[0], None)
  339.     return inevow.IHand(co, None)
  340.  
  341.  
  342. def statusFactory(ctx):
  343.     co = _CARRYOVER.get(ctx.tag.args.get('_nevow_carryover_', [
  344.         None])[0], None)
  345.     return inevow.IStatusMessage(co, None)
  346.  
  347.  
  348. def originalFactory(ctx):
  349.     return ctx.tag
  350.  
  351.  
  352. class Fragment(DataFactory, RenderFactory, MacroFactory, ConfigurableMixin):
  353.     """A fragment is a renderer that can be embedded in a stan document and
  354.     hooks its template (from the docFactory) up to its data_ and render_
  355.     methods, i.e. it remembers itself as the IRendererFactory and IContainer.
  356.  
  357.     Fragment primarily serves as the base for Page, Nevow's web resource, but
  358.     it can be used for more complex rendering. For instance, a fragment might
  359.     be used to encapsulate the rendering of a complex piece of data where the
  360.     template is read from disk and contains standard renderers (sequence,
  361.     mapping etc) and/or custom render methods.
  362.     """
  363.     implements(inevow.IRenderer, inevow.IGettable)
  364.     docFactory = None
  365.     original = None
  366.     
  367.     def __init__(self, original = None, docFactory = None):
  368.         if original is not None:
  369.             self.original = original
  370.         
  371.         self.toremember = []
  372.         if docFactory is not None:
  373.             self.docFactory = docFactory
  374.         
  375.  
  376.     
  377.     def get(self, context):
  378.         return self.original
  379.  
  380.     
  381.     def rend(self, context, data):
  382.         context = WovenContext(parent = context)
  383.         self.rememberStuff(context)
  384.         preprocessors = _getPreprocessors(self)
  385.         old = self.docFactory.pattern
  386.         self.docFactory.pattern = 'content'
  387.         self.docFactory.precompiledDoc = None
  388.         
  389.         try:
  390.             
  391.             try:
  392.                 doc = self.docFactory.load(context, preprocessors)
  393.             finally:
  394.                 self.docFactory.pattern = old
  395.                 self.docFactory.precompiledDoc = None
  396.  
  397.         except TypeError:
  398.             e = None
  399.             if 'nevow.inevow.IQ' not in str(e):
  400.                 raise 
  401.             'nevow.inevow.IQ' not in str(e)
  402.             doc = self.docFactory.load(context, preprocessors)
  403.         except NodeNotFound:
  404.             doc = self.docFactory.load(context, preprocessors)
  405.  
  406.         if old == 'content':
  407.             warnings.warn("[v0.5] Using a Page with a 'content' pattern is\n                               deprecated.", DeprecationWarning, stacklevel = 2)
  408.         
  409.         context.tag = tags.invisible[doc]
  410.         return context
  411.  
  412.     
  413.     def remember(self, obj, inter = None):
  414.         '''Remember an object for an interface on new PageContexts which are
  415.         constructed around this Page. Whenever this Page is involved in object
  416.         traversal in the future, all objects will be visible to .locate() calls
  417.         at the level of a PageContext wrapped around this Page and all contexts
  418.         below it.
  419.  
  420.         This does not affect existing Context instances.
  421.         '''
  422.         self.toremember.append((obj, inter))
  423.  
  424.     
  425.     def rememberStuff(self, ctx):
  426.         ctx.remember(self, inevow.IRenderer)
  427.         ctx.remember(self, inevow.IRendererFactory)
  428.         ctx.remember(self, inevow.IMacroFactory)
  429.         ctx.remember(self, inevow.IData)
  430.  
  431.  
  432.  
  433. class ChildLookupMixin(FreeformChildMixin):
  434.     children = None
  435.     
  436.     def locateChild(self, ctx, segments):
  437.         '''Locate a child page of this one. ctx is a
  438.         nevow.context.PageContext representing the parent Page, and segments
  439.         is a tuple of each element in the URI. An tuple (page, segments) should be
  440.         returned, where page is an instance of nevow.rend.Page and segments a tuple
  441.         representing the remaining segments of the URI. If the child is not found, return
  442.         NotFound instead.
  443.  
  444.         locateChild is designed to be easily overridden to perform fancy lookup tricks.
  445.         However, the default locateChild is useful, and looks for children in three places,
  446.         in this order:
  447.  
  448.          - in a dictionary, self.children
  449.          - a member of self named child_<childname>. This can be either an
  450.            attribute or a method. If an attribute, it should be an object which
  451.            can be adapted to IResource. If a method, it should take the context
  452.            and return an object which can be adapted to IResource.
  453.          - by calling self.childFactory(ctx, name). Name is a single string instead
  454.            of a tuple of strings. This should return an object that can be adapted
  455.            to IResource.
  456.         '''
  457.         if self.children is not None:
  458.             r = self.children.get(segments[0], None)
  459.             if r is not None:
  460.                 return (r, segments[1:])
  461.         
  462.         w = getattr(self, 'child_%s' % segments[0], None)
  463.         r = self.childFactory(ctx, segments[0])
  464.         if r is not None:
  465.             return (r, segments[1:])
  466.         return FreeformChildMixin.locateChild(self, ctx, segments)
  467.  
  468.     
  469.     def childFactory(self, ctx, name):
  470.         '''Used by locateChild to return children which are generated
  471.         dynamically. Note that higher level interfaces use only locateChild,
  472.         and only nevow.rend.Page.locateChild uses this.
  473.  
  474.         segment is a string representing one element of the URI. Request is a
  475.         nevow.appserver.NevowRequest.
  476.  
  477.         The default implementation of this always returns None; it is intended
  478.         to be overridden.'''
  479.         pass
  480.  
  481.     
  482.     def putChild(self, name, child):
  483.         if self.children is None:
  484.             self.children = { }
  485.         
  486.         self.children[name] = child
  487.  
  488.  
  489.  
  490. class Page(Fragment, ConfigurableFactory, ChildLookupMixin):
  491.     '''A page is the main Nevow resource and renders a document loaded
  492.     via the document factory (docFactory).
  493.     '''
  494.     implements(inevow.IResource)
  495.     buffered = False
  496.     beforeRender = None
  497.     afterRender = None
  498.     addSlash = None
  499.     
  500.     flattenFactory = lambda self, *args: flat.flattenFactory(*args)
  501.     
  502.     def renderHTTP(self, ctx):
  503.         if self.beforeRender is not None:
  504.             return (util.maybeDeferred(self.beforeRender, ctx).addCallback,)((lambda result, ctx: self._renderHTTP(ctx)), ctx)
  505.         return self._renderHTTP(ctx)
  506.  
  507.     
  508.     def _renderHTTP(self, ctx):
  509.         request = inevow.IRequest(ctx)
  510.         if self.addSlash and inevow.ICurrentSegments(ctx)[-1] != '':
  511.             request.redirect(request.URLPath().child(''))
  512.             return ''
  513.         log.msg(http_render = None, uri = request.uri)
  514.         self.rememberStuff(ctx)
  515.         
  516.         def finishRequest():
  517.             carryover = request.args.get('_nevow_carryover_', [
  518.                 None])[0]
  519.             if carryover is not None and _CARRYOVER.has_key(carryover):
  520.                 del _CARRYOVER[carryover]
  521.             
  522.             if self.afterRender is not None:
  523.                 return util.maybeDeferred(self.afterRender, ctx)
  524.  
  525.         preprocessors = _getPreprocessors(self)
  526.         doc = self.docFactory.load(ctx, preprocessors)
  527.         ctx = WovenContext(ctx, tags.invisible[doc])
  528.         return self.flattenFactory(doc, ctx, writer, finisher)
  529.  
  530.     
  531.     def rememberStuff(self, ctx):
  532.         Fragment.rememberStuff(self, ctx)
  533.         ctx.remember(self, inevow.IResource)
  534.  
  535.     
  536.     def renderString(self, ctx = None):
  537.         '''Render this page outside of the context of a web request, returning
  538.         a Deferred which will result in a string.
  539.  
  540.         If twisted is not installed, this method will return a string result immediately,
  541.         and this method is equivalent to renderSynchronously.
  542.         '''
  543.         io = StringIO()
  544.         writer = io.write
  545.         
  546.         def finisher(result):
  547.             return io.getvalue()
  548.  
  549.         ctx = PageContext(parent = ctx, tag = self)
  550.         self.rememberStuff(ctx)
  551.         doc = self.docFactory.load(ctx)
  552.         ctx = WovenContext(ctx, tags.invisible[doc])
  553.         return self.flattenFactory(doc, ctx, writer, finisher)
  554.  
  555.     
  556.     def renderSynchronously(self, ctx = None):
  557.         '''Render this page synchronously, returning a string result immediately.
  558.         Raise an exception if a Deferred is required to complete the rendering
  559.         process.
  560.         '''
  561.         io = StringIO()
  562.         ctx = PageContext(parent = ctx, tag = self)
  563.         self.rememberStuff(ctx)
  564.         doc = self.docFactory.load(ctx)
  565.         ctx = WovenContext(ctx, tags.invisible[doc])
  566.         
  567.         def raiseAlways(item):
  568.             raise NotImplementedError('renderSynchronously can not support rendering: %s' % (item,))
  569.  
  570.         list(flat.iterflatten(doc, ctx, io.write, raiseAlways))
  571.         return io.getvalue()
  572.  
  573.     
  574.     def child_(self, ctx):
  575.         '''When addSlash is True, a page rendered at a url with no
  576.         trailing slash and a page rendered at a url with a trailing
  577.         slash will be identical. addSlash is useful for the root
  578.         resource of a site or directory-like resources.
  579.         '''
  580.         if self.addSlash and len(inevow.IRemainingSegments(ctx)) == 1:
  581.             return self
  582.  
  583.     
  584.     def webFormPost(self, request, res, configurable, ctx, bindingName, args):
  585.         '''Accept a web form post, either redisplaying the original form (with
  586.         errors) if validation fails, or redirecting to the appropriate location after
  587.         the post succeeds. This hook exists specifically for formless.
  588.  
  589.         New in 0.5, _nevow_carryover_ is only used if an autocallable method
  590.         returns a result that needs to be carried over.
  591.  
  592.         New in 0.5, autocallables may return a nevow.url.URL or URLOverlay
  593.         instance rather than setting IRedirectAfterPost on the request.
  594.  
  595.         New in 0.5, autocallables may return a Page instance to have that Page
  596.         instance rendered at the post target URL with no redirects at all. Useful
  597.         for multi-step wizards.
  598.         '''
  599.         
  600.         def redirectAfterPost(aspects):
  601.             hand = aspects.get(inevow.IHand)
  602.             refpath = None
  603.             if hand is not None:
  604.                 if isinstance(hand, Page):
  605.                     refpath = url.here
  606.                     if 'freeform_hand' not in inevow.IRequest(ctx).prepath:
  607.                         refpath = refpath.child('freeform_hand')
  608.                     
  609.                 
  610.                 if isinstance(hand, (url.URL, url.URLOverlay)):
  611.                     refpath = hand
  612.                     hand = None
  613.                 
  614.             
  615.             if refpath is None:
  616.                 redirectAfterPost = request.getComponent(iformless.IRedirectAfterPost, None)
  617.                 if redirectAfterPost is None:
  618.                     ref = request.getHeader('referer')
  619.                     if ref:
  620.                         refpath = url.URL.fromString(ref)
  621.                     else:
  622.                         refpath = url.here
  623.                 else:
  624.                     warnings.warn('[0.5] IRedirectAfterPost is deprecated. Return a URL instance from your autocallable instead.', DeprecationWarning, 2)
  625.                     ref = str(redirectAfterPost)
  626.                     refpath = url.URL.fromString(ref)
  627.             
  628.             if hand is not None or aspects.get(iformless.IFormErrors) is not None:
  629.                 magicCookie = '%s%s%s' % (now(), request.getClientIP(), random.random())
  630.                 refpath = refpath.replace('_nevow_carryover_', magicCookie)
  631.                 _CARRYOVER[magicCookie] = C = tpc.Componentized()
  632.                 for k, v in aspects.iteritems():
  633.                     C.setComponent(k, v)
  634.                 
  635.             
  636.             destination = flat.flatten(refpath, ctx)
  637.             request.redirect(destination)
  638.             static = static
  639.             import nevow
  640.             return (static.Data('You posted a form to %s' % bindingName, 'text/plain'), ())
  641.  
  642.         return util.maybeDeferred(configurable.postForm, ctx, bindingName, args).addCallback(self.onPostSuccess, request, ctx, bindingName, redirectAfterPost).addErrback(self.onPostFailure, request, ctx, bindingName, redirectAfterPost)
  643.  
  644.     
  645.     def onPostSuccess(self, result, request, ctx, bindingName, redirectAfterPost):
  646.         if result is None:
  647.             message = '%s success.' % formless.nameToLabel(bindingName)
  648.         else:
  649.             message = result
  650.         return redirectAfterPost({
  651.             inevow.IHand: result,
  652.             inevow.IStatusMessage: message })
  653.  
  654.     
  655.     def onPostFailure(self, reason, request, ctx, bindingName, redirectAfterPost):
  656.         reason.trap(formless.ValidateError)
  657.         return redirectAfterPost({
  658.             iformless.IFormErrors: {
  659.                 bindingName: reason.value } })
  660.  
  661.  
  662.  
  663. def sequence(context, data):
  664.     '''Renders each item in the sequence using patterns found in the
  665.     children of the element.
  666.  
  667.     Sequence recognises the following patterns:
  668.  
  669.      - header: Rendered at the start, before the first item. If multiple
  670.        header patterns are provided they are rendered together in the
  671.        order they were defined.
  672.  
  673.      - footer: Just like the header only renderer at the end, after the
  674.        last item.
  675.  
  676.      - item: Rendered once for each item in the sequence. If multiple
  677.        item patterns are provided then the pattern is cycled in the
  678.        order defined.
  679.  
  680.      - divider: Rendered once between each item in the sequence. Multiple
  681.        divider patterns are cycled.
  682.  
  683.      - empty: Rendered instead of item and divider patterns when the
  684.        sequence contains no items.
  685.  
  686.     Example::
  687.  
  688.      <table nevow:render="sequence" nevow:data="peopleSeq">
  689.        <tr nevow:pattern="header">
  690.          <th>name</th>
  691.          <th>email</th>
  692.        </tr>
  693.        <tr nevow:pattern="item" class="odd">
  694.          <td>name goes here</td>
  695.          <td>email goes here</td>
  696.        </tr>
  697.        <tr nevow:pattern="item" class="even">
  698.          <td>name goes here</td>
  699.          <td>email goes here</td>
  700.        </tr>
  701.        <tr nevow:pattern="empty">
  702.          <td colspan="2"><em>they\'ve all gone!</em></td>
  703.        </tr>
  704.      </table>
  705.  
  706.     '''
  707.     tag = context.tag
  708.     headers = tag.allPatterns('header')
  709.     pattern = tag.patternGenerator('item')
  710.     divider = tag.patternGenerator('divider', default = tags.invisible)
  711.     content = [ (pattern(data = element), divider(data = element)) for element in data ]
  712.     footers = tag.allPatterns('footer')
  713.     return tag.clear()[(headers, content, footers)]
  714.  
  715.  
  716. def mapping(context, data):
  717.     '''Fills any slots in the element\'s children with data from a
  718.     dictionary. The dict keys are used as the slot names, the dict
  719.     values are used as filling.
  720.  
  721.     Example::
  722.  
  723.      <tr nevow:render="mapping" nevow:data="personDict">
  724.        <td><nevow:slot name="name"/></td>
  725.        <td><nevow:slot name="email"/></td>
  726.      </tr>
  727.     '''
  728.     for k, v in data.items():
  729.         context.fillSlots(k, v)
  730.     
  731.     return context.tag
  732.  
  733.  
  734. def string(context, data):
  735.     return context.tag.clear()[str(data)]
  736.  
  737.  
  738. def data(context, data):
  739.     """Replace the tag's content with the current data.
  740.     """
  741.     return context.tag.clear()[data]
  742.  
  743.  
  744. class FourOhFour:
  745.     '''A simple 404 (not found) page.
  746.     '''
  747.     implements(inevow.IResource)
  748.     notFound = "<html><head><title>Page Not Found</title></head><body>Sorry, but I couldn't find the object you requested.</body></html>"
  749.     original = None
  750.     
  751.     def locateChild(self, ctx, segments):
  752.         return NotFound
  753.  
  754.     
  755.     def renderHTTP(self, ctx):
  756.         inevow.IRequest(ctx).setResponseCode(404)
  757.         
  758.         try:
  759.             notFoundHandler = ctx.locate(inevow.ICanHandleNotFound)
  760.         except KeyError:
  761.             e = None
  762.             return self.notFound
  763.  
  764.         
  765.         try:
  766.             return notFoundHandler.renderHTTP_notFound(PageContext(parent = ctx, tag = notFoundHandler))
  767.         except:
  768.             log.err()
  769.             return self.notFound
  770.  
  771.  
  772.     
  773.     def __nonzero__(self):
  774.         return False
  775.  
  776.  
  777. NotFound = (None, ())
  778.